package cn.oi.klittle.era.utils

import net.sourceforge.pinyin4j.PinyinHelper
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType


/**
 * fixme 汉字转拼音工具类;参照：https://blog.csdn.net/zhuwentao2150/article/details/70230341
 */
object KPinyin4jUtils {

    var defalutFormat: HanyuPinyinOutputFormat? = null

    //获取输入格式
    fun getDefaultFormat(): HanyuPinyinOutputFormat? {
        //setToneType 设置音标的显示方式：
        //HanyuPinyinToneType.WITH_TONE_MARK：在拼音字母上显示音标，如“zhòng”
        //HanyuPinyinToneType.WITH_TONE_NUMBER：在拼音字符串后面通过数字显示，如“zhong4”
        //HanyuPinyinToneType.WITHOUT_TONE：不显示音标

        //setCaseType 设置拼音大小写：
        //HanyuPinyinCaseType.LOWERCASE：返回的拼音为小写字母
        //HanyuPinyinCaseType.UPPERCASE：返回的拼音为大写字母

        //setVCharType 设置拼音字母“ü”的显示方式
        //汉语拼音中的“ü”不能简单的通过英文来表示，所以需要单独定义“ü”的显示格式
        //HanyuPinyinVCharType.WITH_U_UNICODE：默认的显示方式，输出“ü”
        //HanyuPinyinVCharType.WITH_V：输出“v”
        //HanyuPinyinVCharType.WITH_U_AND_COLON：输出“u:”

        if (defalutFormat == null) {
            defalutFormat = HanyuPinyinOutputFormat()
            defalutFormat?.toneType = HanyuPinyinToneType.WITHOUT_TONE//不显示音标
            defalutFormat?.vCharType = HanyuPinyinVCharType.WITH_V//汉语拼音中的“ü” 输出“v”
            defalutFormat?.caseType = HanyuPinyinCaseType.LOWERCASE//返回的拼音为小写字母
        }
        return defalutFormat
    }

    /**
     * 汉语转拼音;字母小写；如：中国 : zhongguo
     * @param cStr 中文字符。如果传入的是一个非汉字，则会返回null
     */
    fun toHanyuPinyinString(cStr: String?): String? {
        cStr?.trim()?.let {
            if (it.length > 0) {
                var cStrHY: String? = ""
                it.toCharArray()?.forEach {
                    toHanyuPinyinString(it)?.let {
                        if (it != null) {
                            cStrHY += it
                        }
                    }
                }
                cStrHY?.let {
                    if (it.length > 0) {
                        return it
                    }
                }
            }
        }
        return null
    }

    /**
     * 汉语转拼音;（一般就返回一个，有多音字时才会返回多个）
     */
    fun toHanyuPinyinStringArray(cStr: String?): ArrayList<String>? {
        cStr?.trim()?.let {
            var cStrHYs: ArrayList<ArrayList<String>>? = ArrayList()
            if (it.length > 0) {
                it.toCharArray()?.forEach {
                    var cStrHY = ArrayList<String>()
                    toHanyuPinyinStringArray(it)?.forEach {
                        if (it != null) {
                            cStrHY.add(it)
                        }
                    }
                    if (cStrHY.size>0) {
                        cStrHYs?.add(cStrHY)
                    }
                }
            }
            //KLoggerUtils.e("cStrHYs:\t" + cStrHYs)
            cStrHYs?.let {
                if (it.size > 0) {
                    var cStrHYs2 = ArrayList<String>()
                    combination(cStrHYs, 0, cStrHYs2, "")
                    if (cStrHYs2.size > 0) {
                        return cStrHYs2
                    }
                }
            }
        }
        return null
    }

    /**
     * 汉语转拼音(首字母);字母小写; 如：中国 : zg
     */
    fun toHanyuPinyinFirst(cStr: String?): String? {
        cStr?.trim()?.let {
            if (it.length > 0) {
                var cStrHY: String? = ""
                it.toCharArray()?.forEach {
                    toHanyuPinyinString(it)?.trim()?.let {
                        if (it.length > 0) {
                            cStrHY += it.substring(0, 1)
                        }
                    }
                }
                cStrHY?.let {
                    if (it.length > 0) {
                        return it
                    }
                }
            }
        }
        return null
    }

    /**
     * 汉语转拼音(首字母);字母小写; （一般就返回一个，有多音字时才会返回多个）
     */
    fun toHanyuPinyinFirstArray(cStr: String?): ArrayList<String>? {
        cStr?.trim()?.let {
            var cStrHYs: ArrayList<ArrayList<String>>? = ArrayList()
            if (it.length > 0) {
                it.toCharArray()?.forEach {
                    var cStrHY = ArrayList<String>()
                    toHanyuPinyinStringArray(it)?.forEach {
                        if (it != null && it.length > 0) {
                            var it = it.substring(0, 1)
                            if (!cStrHY.contains(it)) {
                                cStrHY.add(it)
                            }
                        }
                    }
                    if (cStrHY.size>0) {
                        cStrHYs?.add(cStrHY)
                    }
                }
            }
            //KLoggerUtils.e("cStrHYs:\t" + cStrHYs)
            cStrHYs?.let {
                if (it.size > 0) {
                    var cStrHYs2 = ArrayList<String>()
                    combination(cStrHYs, 0, cStrHYs2, "")
                    if (cStrHYs2.size > 0) {
                        return cStrHYs2
                    }
                }
            }
        }
        return null
    }


    /**
     * fixme 同时获取拼音数组和首字母
     * @param cStrHYsP 拼音集合
     * @param cStrHYsF 首字母集合
     */
    fun toHanyuPinyinStringArrayAndFirstArray(cStr: String?, cStrHYsP: ArrayList<String>, cStrHYsF: ArrayList<String>) {
        cStr?.trim()?.let {
            var cStrHYs_p: ArrayList<ArrayList<String>>? = ArrayList()//拼音集合
            var cStrHYs_f: ArrayList<ArrayList<String>>? = ArrayList()//首字母集合
            if (it.length > 0) {
                it.toCharArray()?.forEach {
                    var cStrHY_p = ArrayList<String>()
                    var cStrHY_f = ArrayList<String>()
                    toHanyuPinyinStringArray(it)?.forEach {
                        it?.trim()?.let {
                            if (it.length > 0) {
                                cStrHY_p?.add(it)
                                var it = it.substring(0, 1)
                                if (!cStrHY_f.contains(it)) {
                                    cStrHY_f.add(it)
                                }
                            }
                        }
                    }
                    if (cStrHY_p.size > 0) {
                        cStrHYs_p?.add(cStrHY_p)
                    }
                    if (cStrHY_f.size > 0) {
                        cStrHYs_f?.add(cStrHY_f)
                    }
                }
            }
            //KLoggerUtils.e("cStrHYs_p:\t" + cStrHYs_p)
            cStrHYs_p?.let {
                if (it.size > 0) {
                    combination(it, 0, cStrHYsP, "")
                }
            }
            cStrHYs_f?.let {
                if (it.size > 0) {
                    combination(it, 0, cStrHYsF, "")
                }
            }
        }
    }

    /**
     * fixme ArrayList内部字符自由组合;想了一整天我。
     * @param cStrHYs 总数据
     * @param index 当前轮询下标
     * @param cStrHYs2 组合数据集合
     * @param cStrHYs3 当前字符
     */
    private fun combination(cStrHYs: ArrayList<ArrayList<String>>, index: Int, cStrHYs2: ArrayList<String>, cStrHYs3: String) {
        cStrHYs?.let {
            if (it.size > 0) {
                var last = it.lastIndex
                it[index]?.let {
                    if (index < 4) {
                        it.forEach {
                            var cStr = it
                            var cStrHYs3 = cStrHYs3 + cStr
                            if (index == last) {
                                cStrHYs2?.add(cStrHYs3)
                            } else {
                                var index = index + 1
                                combination(cStrHYs, index, cStrHYs2, cStrHYs3)
                            }
                        }
                    } else {
                        var cStr = it[0]//fixme 第四位数开始，就不轮询了。就只组合前面四位。防止数据过大卡死。
                        var cStrHYs3 = cStrHYs3 + cStr
                        if (index == last) {
                            cStrHYs2?.add(cStrHYs3)
                        } else {
                            var index = index + 1
                            combination(cStrHYs, index, cStrHYs2, cStrHYs3)
                        }
                    }
                }
            }
        }
    }


    fun toHanyuPinyinStringArray(char: Char?): MutableList<String>? {
        char?.let {
            //默认格式：返回一个String数组，包含文字的所有可能出现的读音。如果传入的是一个非汉字，则会返回null，后面的数字代表读音的第几声；如 好 -> hao3 hao4
            //getDefaultFormat() ：小写，没有音标。
            var format = getDefaultFormat()
            PinyinHelper.toHanyuPinyinStringArray(it, format)?.let {
                var datas = it
                format?.let {
                    if (it.toneType == HanyuPinyinToneType.WITHOUT_TONE) {
                        //不显示音标，就忽悠音标不同
                        var list = ArrayList<String>()
                        datas.forEach {
                            if (!list.contains(it)) {
                                list.add(it)
                            }
                        }
                        if (list.size > 0) {
                            return list
                        }
                    }
                }
                return it.toMutableList()
            }
        }
        return null
    }

    fun toHanyuPinyinString(char: Char?): String? {
        char?.let {
            PinyinHelper.toHanyuPinyinStringArray(it, getDefaultFormat())?.let {
                if (it.size >= 0) {
                    return it[0]//现在就返回第一个拼音，小写且不带音标。
                }
            }
        }
        return null
    }

}